Xamarin.iOS 文字列の描画
1 はじめに
今回は、Xamarin.iOSの文字列描画です。 Xamarin.iOSの「NSString」には、DrawString()というメソッドがあり、簡単に文字列が描画できます。
サンプルは、UIViewのDraw()への描画になっています。Xamarin.iOSでのUIViewのサブクラス化がピンとこない場合は、下記をご参照ください。
Xamarin.iOS テンプレート(Single View App)
なお、図形(直線・矩形・円)の描画に使用していた「グラフィックコンテキスト」は、ここでは必要ありません。
2 フォント
DrawString()で文字列を描画する際、最低限フォン ト(UIFont)の指定が必要ですが、このフォントを簡単に取得する方法として下記の4種類があります。
- UIFont.SystemFontOfSize(nfroat size) //システムフォント
- UIFont.BoldSystemFontOfSize(nfroat size) //ボールド
- UIFont.ItalicSystemFontOfSize(nfroat size) //イタリック
- UIFont.FromName(string name,nfroat size) //フォント名で指定
色々なフォントを取得して文字列を描画してみたサンプルは、次のようになります。
public override void Draw(CGRect rect) { base.Draw(rect); var str = new NSString("Developers.IO"); const int size = 30; //フォントサイズ(30pt) const int x = 40; var y = 50; //システムフォントで描画する str.DrawString(new CGPoint(x, y += 50), UIFont.SystemFontOfSize(size)); //ボールドフォントで描画する str.DrawString(new CGPoint(x, y += 50), UIFont.BoldSystemFontOfSize(size)); //イタリックフォントで描画する str.DrawString(new CGPoint(x, y += 50), UIFont.ItalicSystemFontOfSize(size)); //Helvetica-Boldフォントで描画する str.DrawString(new CGPoint(x, y += 50), UIFont.FromName("Helvetica-Bold", size)); }
フォント名は、UIFont.FontNamesForFamilyName(family)でフォントファミリーごとに列挙が可能です。また、フォントファミリーは、UIFont.FamilyNamesで列挙できます。 下記のコードは、iOS端末で利用可能なフォントをすべて列挙したものです。
public override void Draw(CGRect rect) { base.Draw(rect); const int size = 10; //フォントのサイズ(12pt) const int x = 20; const int h = 15; var y = 0; //フォントファミリーを列挙 foreach (var family in UIFont.FamilyNames) { //フォントファミリー名の表示 ((NSString)("[Family] " + family)).DrawString(new CGPoint(x, y += h), UIFont.SystemFontOfSize(size)); //フォントファミリに属するフォントを列挙 foreach (var n in UIFont.FontNamesForFamilyName(family)) { //当該フォントを使用してフォント名を表示 ((NSString)n).DrawString(new CGPoint(x + 20, y += h), UIFont.FromName(n, size)); } } }
フォントのサンプルとして、最後にiPhoneに標準でインストールされている日本語フォントである「ヒラギノ」のゴシック体と明朝体を表示してみます。
public override void Draw(CGRect rect) { base.Draw(rect); var x = 20; var y = 20; var ar = new List<String>{ "Hiragino Kaku Gothic ProN W3", "Hiragino Kaku Gothic ProN W6", "Hiragino Mincho ProN W3", "Hiragino Mincho ProN W6" }; foreach (var font in ar.Select(n => UIFont.FromName(n, 25))) { ((NSString)"クラスメソッド株式会社").DrawString(new CGPoint(x, y += 35), font); } }
3 文字列属性
NSStringのDrawString()には、先のようにフォントだけでなく、属性(UIStringAttributes)を指定してできるものもあります。
public override void Draw(CGRect rect) { base.Draw(rect); const int x = 20; const int y = 50; //属性の生成 var attr = new UIStringAttributes { ForegroundColor = UIColor.White,//文字色(白色) BackgroundColor = UIColor.Orange,//背景色(オレンジ色) Font = UIFont.FromName("Courier", 35f),//フォント Courier 35ポイント UnderlineColor = UIColor.Red,//下線色( 赤色) UnderlineStyle = NSUnderlineStyle.Double//下線スタイル(2重) }; //表示位置と属性を指定して文字列を表示する ((NSString)"Developers.IO").DrawString(new CGPoint(x, y), attr); }
指定可能な属性には、下記のようなものが指定可能です。
- BackgroundColor 文字の背景色
- BaselineOffset ベースラインからのオフセット
- Font フォント属性
- ForegroundColor 文字の色
- KerningAdjustment カーニング
- Ligature リガチャをするか否か
- ParagraphStyle 段落の書式
- Shadow //影
- StrikethroughColor
- StrikethroughStyle
- StrokeColor 枠線の色
- StrokeWidth 枠線の幅
- UnderlineColor 下線の色
- UnderlineStyle 下線のスタイル
詳しくは下記のリンクをご参照ください。
Xamarin Devepolers [UIKit.UIStringAttributeKey Class]
4 範囲を指定した文字列描画
NSStringのWeakDrawString()を使用すると、矩形内に文字列を描画できます。 第2パラメータに必要とされる属性は、NSDirectoryですが、こちらは、UIStringAttributesを生成して、そのパラメータ(Dictionary)を使用できます。
public override void Draw(CGRect rect) { base.Draw(rect); //NSStringの生成 var str = new NSString("智に働けば角が立つ。情に棹させば流される。意地を通せば窮屈だ。兎角に人の世は住みにくい。住みにくさが高じると、安い所へ引き越したくなる。どこへ越しても住みにくいと悟つた時、詩が生れて、畫が出來る。人の世を作ったものは神でもなければ鬼でもない。矢張り向ふ三軒兩隣りにちらちらする唯の人である。唯の人が作つた人の世が住みにくいからとて、越す國はあるまい。あれば人でなしの國へ行く許りだ。人でなしの國は人の世よりも猶住みにくからう。"); //属性(フォントのみ指定)の生成 var attr = new UIStringAttributes { Font = UIFont.SystemFontOfSize(15) }; //指定範囲の中に描画(オーバした部分は、カットされる) str.WeakDrawString(new CGRect(40, 40, 240, 240), attr.Dictionary); }
5 文字サイズの取得
文字列を描画する面積を取得したい場合があります。 NSStringのStringSize()で取得が可能ですが、描画面積は、当然フォントのサイズなどによって変化しますので、その指定が必要になります。
public override void Draw(CGRect rect) { base.Draw(rect); const int x = 10; var y = 40; var pt = 10; Disp("10ポイントの文字列", x, y += pt + 15, pt); pt = 15; Disp("15ポイントの文字列", x, y += pt + 15, pt); pt = 20; Disp("20ポイントの文字列", x, y += pt + 15, pt); pt = 25; Disp("25ポイントの文字列", x, y += pt + 15, pt); pt = 36; Disp("36ポイントの文字列", x, y += pt + 15, pt); } //文字列と座標及びフォントサイズを指定して描画する static void Disp(String str, int x, int y,int fontSize) { //指定されたサイズでシステムフォントを生成する var font = UIFont.SystemFontOfSize(fontSize); //文字列のサイズの取得 var size = ((NSString) str).StringSize(font); //サイズの描画 var s = string.Format("size:{0}×{1}", size.Width, size.Height); ((NSString)s).DrawString(new CGPoint(x, y), UIFont.SystemFontOfSize(12)); //文字列の描画 ((NSString)str).DrawString(new CGPoint(x, y+14), font); }
6 まとめ
今回は、文字列の描画についてまとめてみました。 最初に紹介した通り、文字列の描画では、CGContext(クラフィックコンテキスト)を使用しませんが、記述はDrawメソッド内になると思いまます。 なお、こちらもXamarin.FormsでBoxViewなどのレンダラー拡張で、必要になるかもしれません。